package SqlTool;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JButton;
import javax.swing.JTextField;
import javax.swing.JLabel;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Types;
import java.util.Vector;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JMenu;

public class SqlToolFrame extends JFrame {

	static JPanel contentPane;
	
	
	// 작업할 테이블명은 여기서 한방에 변경
	private String emTargetTable = "emplo2";
	private String deTargetTable = "depart2";
	
	
	static String url = "jdbc:oracle:thin:@127.0.0.1:1521";
	static String user = "hr";
	static String password = "hr";
	
	// manager_id, department_id는 겹친다.
	
	static String employee_id;
	static String first_name;
	static String last_name;
	static String email;
	static String phone_number;
	static String hire_date;
	static String job_id;
	static String salary;
	static String commission_pct;
	static String em_manager_id;
	static String em_department_id;
	static String zipcode;
	static String address;
	
	
	
	static String de_department_id;
	static String department_name;
	static String de_manager_id;
	static String location_id;
	

	
	
	static SqlToolFrame frame;
	static DefaultTableModel dtm;
	
	static Connection conn;
	static PreparedStatement pstmt = null;
	
	static ResultSet rs = null;
	
	
	
	private JMenuBar menuBar;
	private JMenu menuEmplo;
	private JMenu menuDepart;
	private JMenuItem menuItemDeInsert;
	private JMenuItem menuItemDeSearch;
	private JMenuItem menuItemDeModify;
	private JMenuItem menuItemEmInsert;
	private JMenuItem menuItemEmSearch;
	private JMenuItem menuItemEmModify;
	
	

	
	
	

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					frame = new SqlToolFrame();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public SqlToolFrame() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 421);
		
		menuBar = new JMenuBar();
		setJMenuBar(menuBar);
		
		menuEmplo = new JMenu("Employees");
		menuBar.add(menuEmplo);
		
		menuItemEmSearch = new JMenuItem("Search");
		menuItemEmSearch.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				contentPane.removeAll();
				contentPane.add(new EmploSearchPanel());
				contentPane.validate();
			}
		});
		menuEmplo.add(menuItemEmSearch);
		
		menuItemEmModify = new JMenuItem("Modify / Delete");
		menuItemEmModify.setEnabled(false);
		menuEmplo.add(menuItemEmModify);
		
		menuItemEmInsert = new JMenuItem("Insert");
		menuItemEmInsert.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				contentPane.removeAll();
				contentPane.add(new EmploInsertPanel());
				contentPane.validate();
				
			}
		});
		menuEmplo.add(menuItemEmInsert);
		
		menuDepart = new JMenu("Departments");
		menuBar.add(menuDepart);
		
		menuItemDeSearch = new JMenuItem("Search");
		menuItemDeSearch.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				contentPane.removeAll();
				contentPane.add(new DepartSearchPanel());
				contentPane.validate();
			}
		});
		menuDepart.add(menuItemDeSearch);
		
		menuItemDeModify = new JMenuItem("Modify / Delete");
		menuItemDeModify.setEnabled(false);
		menuItemDeModify.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				contentPane.removeAll();
				contentPane.add(new DepartModifyPanel());
				contentPane.validate();
			}
		});
		menuDepart.add(menuItemDeModify);
		
		menuItemDeInsert = new JMenuItem("Insert");
		menuItemDeInsert.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				contentPane.removeAll();
				contentPane.add(new DepartInsertPanel());
				contentPane.validate();
			}
		});
		menuDepart.add(menuItemDeInsert);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);
	}
	
		
	
	
	
	
	// 드라이버 로딩
	// Connection 객체 생성
	// Connection 객체의 인스턴스명은 필드에서 정의

	public void dbConn() {
	
	
	try {
				
		// 1) 오라클 드라이버 로딩
		Class.forName("oracle.jdbc.driver.OracleDriver");

		// 2) 오라클 DB와 연결 (connection 생성)
		// Connection이 Interface 이므로 new로 할 수 없음
		conn = DriverManager.getConnection(url, user, password);

		} catch (Exception ex) {
			ex.printStackTrace();
		}
	
	}

	
	
	// Employees
	
	
	public void emSearch(String keyword) {
		
		dbConn();
		
		// 쿼리 처리
		try {
			// 3) Statement 생성
			String sql = "SELECT * FROM " + emTargetTable + " WHERE employee_id like ?";
			
			// String sql = textFieldSql.getText().trim();
			
			
			pstmt = conn.prepareStatement(sql);

			// parameterIndex 는 ?의 순번. 1부터 시작
			//
			// 이렇게 쓸 수 있어서 PreparedStatement이 편한 거임.
			//
			// pstmt.setInt(1, 5000);
			pstmt.setString(1, keyword); // 숫자는 setInt()로 넣어줘야 함. ㄷㄷ

			System.out.println("keyword : " + keyword);
			// 4) Statement 실행. update, insert, delete는 안됨.
			rs = pstmt.executeQuery();

			
			// 테이블의 타이틀을 지정하기 위해 MetaData 가져옴.
			ResultSetMetaData rsm = rs.getMetaData();
			Vector<String> title = new Vector<>();
			Vector data = null;
			
			dtm = new DefaultTableModel();
			
			
			//
			// zero-base 아님!!! 주의
			//
			// column의 index는 one-base. 시작값, 종료값 index가 달라짐
			//
			for(int i=1; i<=rsm.getColumnCount(); i++) {
				title.add(rsm.getColumnName(i));
			}
			dtm.setColumnIdentifiers(title);
			
			
			
			// 검색 결과는 새 창으로 고고씽~
			
			EmploResultTableFrame result = new EmploResultTableFrame();
			// ResultTableFrame result = new ResultTableFrame(dtm);
			result.setVisible(true);
			

			// table.setModel(dtm);
			
			
			// 5) 실행결과 출력
			while (rs.next()) {
				data = new Vector();
				for(int i=1; i<=rsm.getColumnCount(); i++) {
					
					/*
					System.out.println("i... " + i);
					System.out.println("Types.INTEGER... " + Types.INTEGER);
					System.out.println("Types.NUMERIC... " + Types.NUMERIC);
					System.out.println("Types.DATE... " + Types.DATE);
					System.out.println("rsm.getColumnType(i)... " + rsm.getColumnType(i));
					*/
					
					// NUMBER = Types 2 	// Types.INTEGER -> 4	// Number Mismatch!!!!! NUMERIC을 써야 함
					// VARCHAR2 = Types 12	
					// DATE = Types 93		// Types.DATE -> 91		// Number Mismatch!!!!!
					//
					//
					if(rsm.getColumnType(i) == Types.NUMERIC) {
						data.add(new Integer(rs.getInt(i)));
						
						
					// DATE 형태 컬럼의 값은 날짜까지만 나오도록 수정(split)
					// Types.DATE 값이랑 getColumnType() 값이 서로 안 맞음 -_-;;;;;;;;;
						
					} else if(rsm.getColumnType(i) == (Types.DATE + 2)) {
						data.add(rs.getString(i).split(" ")[0]);
						
					} else {
						data.add(rs.getString(i));
					}
					
				}
				dtm.addRow(data);
			}

		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {
				rs.close();
				pstmt.close();
				conn.close();

			} catch (Exception ex2) {
				ex2.printStackTrace();
			}
		}
	}
	
	

	
	
	public void emInsert(String keyword) {
		
		dbConn();
		
		// 쿼리 처리
		try {
			// 3) Statement 생성
			String sql = "INSERT INTO " + emTargetTable + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
			
			// String sql = textFieldSql.getText().trim();
			
			
			pstmt = conn.prepareStatement(sql);

			// parameterIndex 는 ?의 순번. 1부터 시작
			//
			// 이렇게 쓸 수 있어서 PreparedStatement이 편한 거임.
			//
			// pstmt.setInt(1, 5000);
		
			
			
			// 자료형에 주의!!!!
			
			pstmt.setInt(1, Integer.parseInt(employee_id)); // 숫자는 setInt()로 넣어줘야 함. ㄷㄷ
			pstmt.setString(2, first_name);
			pstmt.setString(3, last_name);
			pstmt.setString(4, email);
			pstmt.setString(5, phone_number); // 숫자는 setInt()로 넣어줘야 함. ㄷㄷ
			pstmt.setString(6, hire_date);
			pstmt.setString(7, job_id);
			pstmt.setInt(8, Integer.parseInt(salary));
			pstmt.setInt(9, Integer.parseInt(commission_pct)); // 숫자는 setInt()로 넣어줘야 함. ㄷㄷ
			pstmt.setInt(10, Integer.parseInt(em_manager_id));
			pstmt.setInt(11, Integer.parseInt(em_department_id));
			pstmt.setString(12, department_name);
			pstmt.setString(13, de_manager_id);
			
			// pstmt.setString(5, keyword);
		
			
			
			System.out.println("keyword : " + keyword);
			
			
			// 4) Statement 실행. update, insert, delete는 안됨.
			int i = pstmt.executeUpdate();

			// i에 따른 결과값 처리

			System.out.println("데이터 추가 완료");
			
			

		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {
				// rs.close();
				pstmt.close();
				conn.close();

			} catch (Exception ex2) {
				ex2.printStackTrace();
			}
		}
	}
	
	
	
	
	
	public void emDelete(String keyword) {
		
		dbConn();
		
		// 쿼리 처리
		try {
			// 3) Statement 생성
			String sql = "DELETE FROM " + emTargetTable + " WHERE employees_id like ?";
			
			// String sql = textFieldSql.getText().trim();
			
			
			pstmt = conn.prepareStatement(sql);

			// parameterIndex 는 ?의 순번. 1부터 시작
			//
			// 이렇게 쓸 수 있어서 PreparedStatement이 편한 거임.
			//
			// pstmt.setInt(1, 5000);
			pstmt.setString(1, keyword); // 숫자는 setInt()로 넣어줘야 함. ㄷㄷ

			System.out.println("keyword : " + keyword);
			// 4) Statement 실행. update, insert, delete는 안됨.
			int i = pstmt.executeUpdate();

			// i에 따른 결과값 처리
			
			System.out.println("데이터 삭제 완료");
			
			

		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {
				// rs.close();
				pstmt.close();
				conn.close();

			} catch (Exception ex2) {
				ex2.printStackTrace();
			}
		}
	}



	public void emModify(String keyword) {
	
	dbConn();
	
	// 쿼리 처리
	try {
		
		// 3) Statement 생성
		String sql = "UPDATE " + emTargetTable + " SET employee_id = ?, first_name = ?, last_name = ?, "
		+ "email = ?, phone_number = ?, hire_date = ?, job_id = ?, salary = ?, commission_pct = ?, "
		+ "em_manager_id = ?, zipcode = ?, address = ? WHERE employee_id like ?";
		
		// String sql = textFieldSql.getText().trim();
		
		
		pstmt = conn.prepareStatement(sql);

		// parameterIndex 는 ?의 순번. 1부터 시작
		//
		// 이렇게 쓸 수 있어서 PreparedStatement이 편한 거임.
		//
		// pstmt.setInt(1, 5000);
		
		
		
		// 자료형에 주의!!!!
		
		pstmt.setInt(1, Integer.parseInt(employee_id)); // 숫자는 setInt()로 넣어줘야 함. ㄷㄷ
		pstmt.setString(2, first_name);
		pstmt.setString(3, last_name);
		pstmt.setString(4, email);
		pstmt.setString(5, phone_number);
		pstmt.setString(6, hire_date);
		pstmt.setString(7, job_id);
		pstmt.setInt(8,  Integer.parseInt(salary));
		pstmt.setInt(9, Integer.parseInt(commission_pct));
		pstmt.setInt(10, Integer.parseInt(em_manager_id));
		pstmt.setInt(11, Integer.parseInt(em_department_id));
		pstmt.setString(12, zipcode);
		pstmt.setString(13, address);
		
		
		pstmt.setString(14, keyword);
	
		
		
		System.out.println("keyword : " + keyword);
		
		
		// 4) Statement 실행. update, insert, delete는 안됨.
		int i = pstmt.executeUpdate();

		// i에 따른 결과값 처리

		System.out.println("데이터 변경 완료");
		
		

	} catch (Exception ex) {
		ex.printStackTrace();
	} finally {
		try {
			// rs.close();
			pstmt.close();
			conn.close();

		} catch (Exception ex2) {
			ex2.printStackTrace();
		}
	}
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	// Department

		
	public void deSearch(String keyword) {
		
		System.out.println("프레임의 find()");
		
		dbConn();
		
		// 쿼리 처리
		try {
			// 3) Statement 생성
			String sql = "SELECT * FROM " + deTargetTable + " WHERE department_id like ?";
			
			// String sql = textFieldSql.getText().trim();
			
			
			pstmt = conn.prepareStatement(sql);

			// parameterIndex 는 ?의 순번. 1부터 시작
			//
			// 이렇게 쓸 수 있어서 PreparedStatement이 편한 거임.
			//
			// pstmt.setInt(1, 5000);
			pstmt.setString(1, keyword); // 숫자는 setInt()로 넣어줘야 함. ㄷㄷ

			System.out.println("keyword : " + keyword);
			// 4) Statement 실행. update, insert, delete는 안됨.
			rs = pstmt.executeQuery();

			
			// 테이블의 타이틀을 지정하기 위해 MetaData 가져옴.
			ResultSetMetaData rsm = rs.getMetaData();
			Vector<String> title = new Vector<>();
			Vector data = null;
			
			dtm = new DefaultTableModel();
			
			
			//
			// zero-base 아님!!! 주의
			//
			// column의 index는 one-base. 시작값, 종료값 index가 달라짐
			//
			for(int i=1; i<=rsm.getColumnCount(); i++) {
				title.add(rsm.getColumnName(i));
			}
			dtm.setColumnIdentifiers(title);
			
			
			
			// 검색 결과는 새 창으로 고고씽~
			
			DepartResultTableFrame result = new DepartResultTableFrame();
			result.setVisible(true);
			

			// table.setModel(dtm);
			
			
			// 5) 실행결과 출력
			while (rs.next()) {
				data = new Vector();
				for(int i=1; i<=rsm.getColumnCount(); i++) {
					
					/*
					System.out.println("i... " + i);
					System.out.println("Types.INTEGER... " + Types.INTEGER);
					System.out.println("Types.NUMERIC... " + Types.NUMERIC);
					System.out.println("Types.DATE... " + Types.DATE);
					System.out.println("rsm.getColumnType(i)... " + rsm.getColumnType(i));
					*/
					
					// NUMBER = Types 2 	// Types.INTEGER -> 4	// Number Mismatch!!!!! NUMERIC을 써야 함
					// VARCHAR2 = Types 12	
					// DATE = Types 93		// Types.DATE -> 91		// Number Mismatch!!!!!
					//
					//
					if(rsm.getColumnType(i) == Types.NUMERIC) {
						data.add(new Integer(rs.getInt(i)));
						
						
					// DATE 형태 컬럼의 값은 날짜까지만 나오도록 수정(split)
					// Types.DATE 값이랑 getColumnType() 값이 서로 안 맞음 -_-;;;;;;;;;
						
					} else if(rsm.getColumnType(i) == (Types.DATE + 2)) {
						data.add(rs.getString(i).split(" ")[0]);
						
					} else {
						data.add(rs.getString(i));
					}
					
				}
				dtm.addRow(data);
			}

		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {
				rs.close();
				pstmt.close();
				conn.close();

			} catch (Exception ex2) {
				ex2.printStackTrace();
			}
		}
	}
	
	

	
	
	public void deInsert(String keyword) {
		
		dbConn();
		
		// 쿼리 처리
		try {
			// 3) Statement 생성
			String sql = "INSERT INTO " + deTargetTable + " VALUES (?, ?, ?, ?)";
			
			// String sql = textFieldSql.getText().trim();
			
			
			pstmt = conn.prepareStatement(sql);

			// parameterIndex 는 ?의 순번. 1부터 시작
			//
			// 이렇게 쓸 수 있어서 PreparedStatement이 편한 거임.
			//
			// pstmt.setInt(1, 5000);
			
			
			
			// 자료형에 주의!!!!
			
			pstmt.setInt(1, Integer.parseInt(de_department_id)); // 숫자는 setInt()로 넣어줘야 함. ㄷㄷ
			pstmt.setString(2, department_name);
			pstmt.setInt(3, Integer.parseInt(de_manager_id));
			pstmt.setInt(4, Integer.parseInt(location_id));
			
			// pstmt.setString(5, keyword);
		
			
			
			System.out.println("keyword : " + keyword);
			
			
			// 4) Statement 실행. update, insert, delete는 안됨.
			int i = pstmt.executeUpdate();

			// i에 따른 결과값 처리

			System.out.println("데이터 추가 완료");
			
			

		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {
				// rs.close();
				pstmt.close();
				conn.close();

			} catch (Exception ex2) {
				ex2.printStackTrace();
			}
		}
	}
	
	
	
	
	
	public void deDelete(String keyword) {
		
		dbConn();
		
		// 쿼리 처리
		try {
			// 3) Statement 생성
			String sql = "DELETE FROM " + deTargetTable + " WHERE department_id like ?";
			
			// String sql = textFieldSql.getText().trim();
			
			
			pstmt = conn.prepareStatement(sql);

			// parameterIndex 는 ?의 순번. 1부터 시작
			//
			// 이렇게 쓸 수 있어서 PreparedStatement이 편한 거임.
			//
			// pstmt.setInt(1, 5000);
			pstmt.setString(1, keyword); // 숫자는 setInt()로 넣어줘야 함. ㄷㄷ

			System.out.println("keyword : " + keyword);
			// 4) Statement 실행. update, insert, delete는 안됨.
			int i = pstmt.executeUpdate();

			// i에 따른 결과값 처리
			
			System.out.println("데이터 삭제 완료");
			
			

		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			try {
				// rs.close();
				pstmt.close();
				conn.close();

			} catch (Exception ex2) {
				ex2.printStackTrace();
			}
		}
	}



	public void deModify(String keyword) {
	
	dbConn();
	
	// 쿼리 처리
	try {
		// 3) Statement 생성
		String sql = "UPDATE " + deTargetTable + " SET department_id = ?, department_name = ?, manager_id = ?, location_id = ? WHERE department_id like ?";
		
		// String sql = textFieldSql.getText().trim();
		
		
		pstmt = conn.prepareStatement(sql);

		// parameterIndex 는 ?의 순번. 1부터 시작
		//
		// 이렇게 쓸 수 있어서 PreparedStatement이 편한 거임.
		//
		// pstmt.setInt(1, 5000);
		
		
		
		// 자료형에 주의!!!!
		
		pstmt.setInt(1, Integer.parseInt(de_department_id)); // 숫자는 setInt()로 넣어줘야 함. ㄷㄷ
		pstmt.setString(2, department_name);
		pstmt.setInt(3, Integer.parseInt(de_manager_id));
		pstmt.setInt(4, Integer.parseInt(location_id));
		pstmt.setString(5, keyword);
	
		
		
		System.out.println("keyword : " + keyword);
		
		
		// 4) Statement 실행. update, insert, delete는 안됨.
		int i = pstmt.executeUpdate();

		// i에 따른 결과값 처리

		System.out.println("데이터 변경 완료");
		
		

	} catch (Exception ex) {
		ex.printStackTrace();
	} finally {
		try {
			// rs.close();
			pstmt.close();
			conn.close();

		} catch (Exception ex2) {
			ex2.printStackTrace();
		}
	}
}

}
